<?php
/**
 * Created by PhpStorm.
 * User: wodrow
 * Date: 7/17/17
 * Time: 12:52 PM
 */

namespace common\components\unionpay;


use common\components\tools\Tools;
use yii\base\Component;
use yii\base\ErrorException;
use yii\httpclient\Client;

/**
 * Class Unionpay
 * @package common\components\unionpay
 *
 * @property SecssUtil $secssUtil
 */
class Unionpay extends Component
{
    const EVENT_BEFORE_SEND = 'event-before-send';
    const EVENT_AFTER_SEND = 'event-after-send';

    public function getSecssUtil()
    {
        $_dir = __DIR__;
        $secssUtil = new SecssUtil();
        $secssUtil->init($_dir."/security.properties");
        return $secssUtil;
    }

    public function send($url, $reqData, $otherData)
    {
        $secssUtil = $this->secssUtil;
        $merNo = isset($otherData['merNo'])&&$otherData['merNo']?$otherData['merNo']:Config::$merchant_id;// 商户号
        $data = [
            'merNo' => $merNo,
            'reqData' => $reqData,
//            'signature' => '', // 签名
        ];
        $data['reqData']['merNo'] = $merNo;
        $data['reqData']['orderDate'] =isset($otherData['orderDate'])&&$otherData['orderDate']?$otherData['orderDate']:date("Ymd");
        $data['reqData']['orderId'] =isset($otherData['orderId'])&&$otherData['orderId']?$otherData['orderId']:Config::$merchant_id.date("YmdHis").rand(100,999);
        if (isset($otherData['busiType'])){
            $data['reqData']['busiType'] = $otherData['busiType'];
        }
        $sensData = $reqData['sensData'];
        $sensData = json_encode($sensData);
        $secssUtil->encryptData($sensData);
        if("00"!==$secssUtil->getErrCode()){
            throw new ErrorException("签名过程发生错误0，错误信息为-->".$secssUtil->getErrMsg());
        }
        $data['reqData']['sensData'] = $secssUtil->getEncValue();
        $data['reqData'] = json_encode($data['reqData'], JSON_UNESCAPED_UNICODE);
        $data['reqData'] = str_replace("\\/", "/", $data['reqData']);
        $data['reqData'] = base64_encode($data['reqData']);
        $sha512 = hash('sha512', $data['reqData']);
        $sData['reqData'] = $sha512;
        $secssUtil->sign($sData);
        if("00"!==$secssUtil->getErrCode()){
            throw new ErrorException("签名过程发生错误1，错误信息为-->".$secssUtil->getErrMsg());
        }
        $data['signature'] = $secssUtil->getSign();
        $this->trigger(self::EVENT_BEFORE_SEND);
        if (isset($otherData['unRequest']) && ($otherData['unRequest'] == 1)){
            $_data = [];
            $_data['sensData']= json_decode($secssUtil->getDecValue());
            $_data['c_post'] = $data;
            return $_data;
        }
        $client = new Client();
        $response = $client->createRequest()
            ->setMethod('post')
            ->setUrl($url)
            ->setData($data)
            ->send();
        $this->trigger(self::EVENT_AFTER_SEND);
        $_data = [];
        $x = Tools::str2arr($response->content, '&');
        foreach ($x as $k => $v){
            $p = strpos($v, '=');
            $_data[substr($v, 0, $p)] = substr($v, $p+1);
        }
        if (isset($_data['respData'])){
            $_data['_respData'] = json_decode(base64_decode($_data['respData']));
            $secssUtil->decryptData($_data['_respData']->sensData);
            if("00"!==$secssUtil->getErrCode()){
                throw new ErrorException("签名过程发生错误2，错误信息为-->".$secssUtil->getErrMsg());
            }
            $_data['unionpay_back'] = $response->content;
            $_data['_respData']->sensData = json_decode($secssUtil->getDecValue());
            $_data['_respData']->c_back = serialize($_data['_respData']);
            $_data['_respData']->c_post = serialize($data);
            $_data = Tools::objectToArray($_data);
            return $_data;
        }else{
            throw new ErrorException("解密过程发生错误，错误信息为-->没有获取到respData");
        }
    }
}